package com.base.invoke.utils;

import com.base.invoke.enums.ExCodeEnum;
import com.base.invoke.exception.CommException;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 排序工具类
 * @author coolpig
 * @date 2019-09-27
 */
public class SortUtil {


    public static final String DESC = "desc";
    public static final String ASC = "asc";

    /**
     *
     * @param list 泛型集合
     * @param field 指定字段
     * @return
     */
    public static List<?> sort(List<?> list, final String field) {
        return sort(list, field, ASC);
    }

    public static List<?> sort(List<?> list, final String field,
                               final String sort) {
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object a, Object b) {
                int ret = 0;
                try {
                    Field f = a.getClass().getDeclaredField(field);
                    f.setAccessible(true);
                    Class<?> type = f.getType();

                    if (type == int.class) {
                        ret = ((Integer) f.getInt(a)).compareTo((Integer) f
                                .getInt(b));
                    } else
                    if (type == double.class) {
                        ret = ((Double) f.getDouble(a)).compareTo((Double) f
                                .getDouble(b));
                    }
                    else if (type == long.class) {
                        ret = ((Long) f.getLong(a)).compareTo((Long) f
                                .getLong(b));
                    } else if (type == float.class) {
                        ret = ((Float) f.getFloat(a)).compareTo((Float) f
                                .getFloat(b));
                    } else if (type == Date.class) {
                        ret = ((Date) f.get(a)).compareTo((Date) f.get(b));
                    } else if (isImplementsOf(type, Comparable.class)) {
                        ret = ((Comparable) f.get(a)).compareTo((Comparable) f
                                .get(b));
                    } else {
                        ret = String.valueOf(f.get(a)).compareTo(
                                String.valueOf(f.get(b)));
                    }

                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (sort.toLowerCase().equals(DESC)) {
                    return -ret;
                } else {
                    return ret;
                }
            }
        });
        return list;
    }

    public static List<?> sort(List<?> list, String[] fields, String[] sorts) {
        if (fields.length != sorts.length){
            throw new CommException(ExCodeEnum.CODE_2, "属性数组元素个数和升降序数组元素个数不相等");
        }
        for (int i = fields.length - 1; i >= 0; i--) {
            final String field = fields[i];
            String tmpSort = ASC;
            if (sorts != null && sorts.length > i && sorts[i] != null) {
                tmpSort = sorts[i];
            }
            final String sort = tmpSort;
            sort(list, field, sort);
        }
        return list;
    }

    public static boolean isImplementsOf(Class<?> clazz, Class<?> szInterface) {
        boolean flag = false;

        Class<?>[] face = clazz.getInterfaces();
        for (Class<?> c : face) {
            if (c == szInterface) {
                flag = true;
            } else {
                flag = isImplementsOf(c, szInterface);
            }
        }

        if (!flag && null != clazz.getSuperclass()) {
            return isImplementsOf(clazz.getSuperclass(), szInterface);
        }

        return flag;
    }
}
